#include "LinkTcpClient.h"
#include <iostream>
#include "TcpClient.h"
#include "lib.h"

using namespace controller;
using namespace hv;

LinkTcpClient::LinkTcpClient() {}
LinkTcpClient::~LinkTcpClient() {}

// 读写接口
bool LinkTcpClient::open(std::map<std::string, std::string> arg)
{
    if (arg.find("url") == arg.end())
    {
        std::cout << "LinkTcpClient 未设置 url" << std::endl;
        return false;
    }
    if (arg.find("port") == arg.end())
    {
        std::cout << "LinkTcpClient 未设置 port" << std::endl;
        return false;
    }
    std::string url = arg["url"];
    std::string port = arg["port"];
    int p = atoi(port.c_str());
    this->_url = url;
    this->_port = p;

    // 1.创建socket
    int fd = this->createsocket(p, url.c_str());
    if (fd < 0)
    {
        std::cout << this->name() << "创建socket失败" << std::endl;
        return false;
    }
    // 2.连接
    this->onConnection = [&](const SocketChannelPtr &channel)
    {
        std::string peeraddr = channel->peeraddr();
        if (channel->isConnected())
        {
            std::cout << this->name() << "连接成功" << std::endl;
            if (this->OnLinkConnect)
            {
                this->OnLinkConnect(this);
            }
        }
        else
        {
            std::cout << this->name() << "连接失败" << std::endl;
            if (this->OnLinkDisconnect)
            {
                this->OnLinkDisconnect(this);
            }
        }
        if (this->isReconnect())
        {
            std::cout << this->name() << "正在重连" << " delay=" << this->reconn_setting->cur_delay << std::endl;
        }
    };

    // 3.发送事件
    this->onWriteComplete = [&](const SocketChannelPtr &channel, Buffer *buf)
    {
        std::cout << this->name() << ">>(" << std::to_string(buf->size()) << "):" << dump_buffer(buf) << std::endl;
        if (this->OnLinkRecv)
        {
            this->OnLinkRecv(this, buf, NULL);
        }
    };

    // 4.接收
    this->onMessage = [&](const SocketChannelPtr &channel, Buffer *buf)
    {
        std::cout << this->name() << "<<(" << std::to_string(buf->size()) << "):" << dump_buffer(buf) << std::endl;
        if (this->OnLinkSend)
        {
            this->OnLinkSend(this, buf, NULL);
        }
    };

    // 5.是否自动重连
    if (arg.find("reconnect") == arg.end() || arg["reconnect"] == "true")
    {

        // reconnect: 1,2,4,8,10,10,10...
        reconn_setting_t reconn;
        reconn_setting_init(&reconn);
        reconn.min_delay = 1000;
        reconn.max_delay = 10000;
        reconn.delay_policy = 2;
        this->setReconnect(&reconn);
    }

    // 6.启动
    this->start();

    return true;
}
bool LinkTcpClient::close()
{
    this->stop();
    return this->isConnected() == false;
}
int LinkTcpClient::write(char *data, int len, const char *arg)
{
    return this->channel->write((const void *)data, len);
}
// int LinkTcpClient::read(char *dataout, int len)
// {
//     return 0;
// }

// 状态
bool LinkTcpClient::is_open()
{
    return this->isConnected();
}
std::string LinkTcpClient::name()
{
    return ("tcp[" + this->_url + ":" + std::to_string(this->_port) + "]");
}
std::string LinkTcpClient::info()
{
    return "tcp-client";
}